using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace HEFramework
{
    /// <summary>
    ///
    /// UI设置数据体编辑器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-01-29 14:37:00
    /// ----------------------------------------
    /// </summary>
    public class UISettingScriptableObjectEditor : EditorWindow
    {
        private const int NAME_LENGTH = 120;
        private const int VALUE_LENGTH = 350;
        private const int NAME_HEIGHT = 18;
        private const int HELP_LENGTH = 475;


        private GUIStyle label;
        private GUIStyle largeLabel;
        private GUIStyle helpBox;
        private GUIStyle textField;
        private GUIStyle vector2Field;


        private UISettingScriptableObject uiSettingScriptableObject;
        private GUILayoutOption[] nameOptions;
        private GUILayoutOption[] valueOptions;


        private bool config;
        private string configFilePath;

        /// <summary>
        /// 打开编辑面板时初始化
        /// </summary>
        private void Awake()
        {
            uiSettingScriptableObject = UISettingScriptableObject.Instance;
            nameOptions = new[] { GUILayout.Width(NAME_LENGTH), GUILayout.Height(NAME_HEIGHT) };
            valueOptions = new[] { GUILayout.Width(VALUE_LENGTH), GUILayout.Height(NAME_HEIGHT) };

            label = new GUIStyle(EditorStyles.label)
            {
                fontSize = 11,
                wordWrap = true,
                richText = true
            };

            largeLabel = new GUIStyle()
            {
                fontStyle = FontStyle.Bold,
                fontSize = 14
            };

            helpBox = new GUIStyle(EditorStyles.helpBox)
            {
                fontSize = 11
            };

            textField = new GUIStyle(EditorStyles.textField)
            {
                fontSize = 11
            };

            vector2Field = new GUIStyle(EditorStyles.textField)
            {
                fontSize = 11
            };

            configFilePath = uiSettingScriptableObject.UIConfigFileBuildPath + "/" + uiSettingScriptableObject.UIConfigFileName + ".cs";
            if (System.IO.File.Exists(configFilePath))
            {
                config = true;
            }
        }


        public static void OpenSettingsWindow()
        {
            try
            {
                if (EditorApplication.isCompiling)
                {
                    return;
                }

                var window = GetWindowWithRect<UISettingScriptableObjectEditor>(new Rect(0, 0, 520, 400), true, "UI Setting", true);
                window.Show();
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }


        private void OnGUI()
        {
            if (uiSettingScriptableObject == null)
            {
                Debug.LogError("Setting data is none.");
            }


            GUILayout.BeginHorizontal();
            GUILayout.Space(5);
            GUILayout.Label("UI设置", largeLabel);
            GUILayout.Space(5);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Space(30);
            if (GUILayout.Button("重置全部", GUILayout.Width(100), GUILayout.Height(20)))
            {
                if (EditorUtility.DisplayDialog("UITool", "确定重置设定？", "是", "否"))
                {
                    UISettingScriptableObject.Instance.ResetAll();
                    EditorUtility.SetDirty(UISettingScriptableObject.Instance);
                }
            }

            GUILayout.Space(10);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("UI预制体生成路径", helpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", label, nameOptions);
            uiSettingScriptableObject.UIPrefabBuildPath = EditorGUILayout.TextField(uiSettingScriptableObject.UIPrefabBuildPath, textField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("UI预制体后缀", helpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("后缀", label, nameOptions);
            uiSettingScriptableObject.UIPrefabExtension = EditorGUILayout.TextField(uiSettingScriptableObject.UIPrefabExtension, textField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("UI配置生成路径", helpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", label, nameOptions);
            uiSettingScriptableObject.UIConfigFileBuildPath = EditorGUILayout.TextField(uiSettingScriptableObject.UIConfigFileBuildPath, textField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("UI画布分别率", helpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("分辨率", label, nameOptions);
            uiSettingScriptableObject.UICanvasScale = EditorGUILayout.Vector2Field("", uiSettingScriptableObject.UICanvasScale);
            GUILayout.EndHorizontal();


            DrawLine();


            if (config)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("UI配置文件已存在", label, nameOptions);
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
                GUILayout.Label(configFilePath, label, GUILayout.Width(400), GUILayout.Height(30));
                GUILayout.EndHorizontal();
            }
            else
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.Button("生成UI配置文件", GUILayout.Width(100), GUILayout.Height(20)))
                {
                    GenerateUIConfigFile();
                    Awake();
                }

                GUILayout.EndHorizontal();
            }


            DrawLine();
            GUILayout.Label("当前预制体模板路径", label, nameOptions);
            GUILayout.Label(uiSettingScriptableObject.UITemplateFilePath, helpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("选择预制体模板路径", GUILayout.Width(150), GUILayout.Height(20)))
            {
                string title = "Open File";
                // 以Assets文件夹为默认目录
                string directory = Application.dataPath;
                // 只显示扩展名为 txt 的文件
                string extension = "txt";
                string path = EditorUtility.OpenFilePanel(title, directory, extension);
                if (path != "")
                {
                    uiSettingScriptableObject.UITemplateFilePath = path.RB();
                }
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("生成UI预制体模板", GUILayout.Width(150), GUILayout.Height(20)))
            {
                GenerateUITemplatePrefab();
            }

            GUILayout.EndHorizontal();
        }


        /// <summary>
        /// 配置文件
        /// </summary>
        private void GenerateUIConfigFile()
        {
            if (!Directory.Exists(uiSettingScriptableObject.UIConfigFileBuildPath))
            {
                Directory.CreateDirectory(uiSettingScriptableObject.UIConfigFileBuildPath);
            }

            //将模板文件复制
            StringBuilder csFile = new StringBuilder(1024);


            csFile.Append("using System.Collections.Generic;\n");
            
            csFile.Append("//------------------------------------------------------------------------------\n");
            csFile.Append("// <auto-generated>\n");
            csFile.Append("//     This code was generated by UITool.\n");
            csFile.Append("//     UIConfig define here.\n");
            csFile.Append("// </auto-generated>\n");
            csFile.Append("//------------------------------------------------------------------------------\n");
            
            csFile.Append("namespace HEFramework\n");
            csFile.Append("{\n");
            
            csFile.Append("public enum eUIFlag\n");
            csFile.Append("{\n");
            csFile.Append("}\n");

            csFile.Append("public class UIConfig\n");
            csFile.Append("{\n");
            csFile.Append("     public Dictionary<string, UIConfigInfo> uiConfigs = new Dictionary<string, UIConfigInfo>()\n");
            csFile.Append("     {\n");
            csFile.Append("           //{eUIFlag.Test.ToString(), new UIConfigInfo() {layer = eUILayer.Bottom, sortingOrder = 10}},\n");
            csFile.Append("     };\n");
            csFile.Append("}\n");
            csFile.Append("}\n");

            string filePath = uiSettingScriptableObject.UIConfigFileBuildPath + "/" + uiSettingScriptableObject.UIConfigFileName + ".cs";
            System.IO.File.WriteAllText(filePath, csFile.ToString(), Encoding.UTF8);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 生产UI模板预制体
        /// </summary>
        private void GenerateUITemplatePrefab()
        {
            if (!System.IO.File.Exists(uiSettingScriptableObject.UITemplateFilePath))
            {
                Debug.LogError(uiSettingScriptableObject.UITemplateFilePath + " -> File not exist.");
                return;
            }

            string content = System.IO.File.ReadAllText(uiSettingScriptableObject.UITemplateFilePath);

            if (!Directory.Exists(uiSettingScriptableObject.UIPrefabBuildPath))
            {
                Directory.CreateDirectory(uiSettingScriptableObject.UIPrefabBuildPath);
            }

            string[] strings = uiSettingScriptableObject.UITemplateFilePath.Split('/');
            string fileName = strings[strings.Length - 1].Replace("txt", "prefab");
            string filePath = uiSettingScriptableObject.UIPrefabBuildPath + "/" + fileName;
            System.IO.File.WriteAllText(filePath, content, Encoding.UTF8);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(filePath);
            obj.GetComponent<CanvasScaler>().referenceResolution = uiSettingScriptableObject.UICanvasScale;

            PrefabUtility.SavePrefabAsset(obj);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 给界面划横线
        /// </summary>
        private void DrawLine()
        {
            GUILayout.Box("", GUILayout.Height(2F), GUILayout.ExpandWidth(true));
        }
    }
}